
package textmining.gpanalysis;

import data.KeywordVector;
import data.Post;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author ibrahimsabek
 */
public class KEUFKeywordVectorGenerator extends KeywordVectorGenerator{

    private static final float eps1 = 1;
    private static final float eps2 = 1;
    private static final float eps3 = 1;

    private int numSentences;

    public KEUFKeywordVectorGenerator(Post post) throws IOException{
        super(post);
        calcNumSentences();
    }

    @Override
    public HashMap<String, Double> generateKeywordsContainer() {
        keywordVector = new HashMap<String, Double>();
        SortedSet<String> keywordSet = createWordSet(new Post[]{this.post});

        //for KEUF algorithm
        for(String keyword : keywordSet){
            try {
                keywordVector.put(keyword, calcTokenWeight(keyword));
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
                Logger.getLogger(KEUFKeywordVectorGenerator.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return keywordVector;
    }

    //generate keywordVector
    public KeywordVector generateKeywordsVector(){
        KeywordVector vector = new KeywordVector();
        vector.setVectorID(post.getpID());
        vector.setData(keywordVector);
        return vector;
    }


    @Override
    protected SortedSet<String> createWordSet(Post[] post) {
        SortedSet<String> keywordSet = new TreeSet<String>();
        keywordSet.addAll(this.PITokenBag.uniqueSet());
        if(post[0].getParaReaders().length > 2 ){
            keywordSet.addAll(this.remPITokenBag.uniqueSet());
        }
        return keywordSet;
    }


    //calculate number of sentences in a post (with relative error)
    private void calcNumSentences(){
        numSentences = AnalyzerUtil.getSentences(post.getBody(), 0).length;
    };
    
    //caculate the token weight relative to its post
    private double calcTokenWeight(String token) throws IOException{
        return calcSV(token) + calcTV(token) + calcCV(token);
    }

    //calculate Sentence weight
    private double calcSV(String token) throws IOException{

        double avrg = 0;

        if(post.getTitleReader() != null){
            avrg = avrg + (eps1 * getTokenFrequency(token, createTokenBag(new Reader[]{post.getTitleReader()})));
        }

        if(PIReaders.length > 0){
            avrg = avrg + (eps2 * getTokenFrequency(token, createTokenBag(new Reader[]{PIReaders[0]})));
            if(PIReaders.length > 1){
                avrg = avrg + (eps3 * getTokenFrequency(token, createTokenBag(new Reader[]{PIReaders[1]})));
            }
        }

        if(remPITokenBag != null){
            
            //implemented using log to the base (e)
            int freq = getTokenFrequency(token, remPITokenBag);
            if(freq > 0){
                return Math.log(getNumSentences()/(freq)) + avrg;
            }else{
                return Math.log(Double.MAX_VALUE) + avrg;
            }
        }else{
            return Math.log(Double.MAX_VALUE) + avrg;
        }
        
        
        
    }

    //calculate Tag Weight
    private double calcTV(String token) throws IOException{
        double avrg = getTokenFrequency(token, createTokenBag(post.getTagsReaders()));
        
        //implemented using log to the base (e)
        int freq = getTokenPostFrequency(token);
        if(freq > 0){
            return Math.log(getNumSentences()/(freq)) + avrg;
        }else{
            return Math.log(Double.MAX_VALUE) + avrg;
        }
    }

    //calculate Category Weight
    private double calcCV(String token) throws IOException{
        double avrg = getTokenFrequency(token, createTokenBag(new Reader[]{post.getCatReader()}));

        //implemented using log to the base (e)
        int freq = getTokenPostFrequency(token);
        if(freq > 0){
            return Math.log(getNumSentences()/(freq)) + avrg;
        }else{
            return Math.log(Double.MAX_VALUE) + avrg;
        }
    }

    private int getNumSentences() {
        return numSentences;
    }




}
